package com.business.dashboard.service.impl;

import com.business.dashboard.dao.UserDao;
import com.business.dashboard.dao.UserFollowDao;
import com.business.dashboard.entity.User;
import com.business.dashboard.entity.UserFollow;
import com.business.dashboard.model.UserLoginRequest;
import com.business.dashboard.model.UserRegisterRequest;
import com.business.dashboard.model.UserUpdateRequest;
import com.business.dashboard.service.UserService;
import com.business.dashboard.utils.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 前端用户服务实现类
 * 
 * @author Claude
 * @since 2025-07-06
 */
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    
    @Autowired
    private UserFollowDao userFollowDao;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil jwtUtil;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public User register(UserRegisterRequest request) {
        // 检查用户名是否已存在
        if (existsByUsername(request.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (existsByEmail(request.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 检查手机号是否已存在
        if (request.getPhone() != null && !request.getPhone().isEmpty() && existsByPhone(request.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 创建用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setName(request.getName());
        user.setCompany(request.getCompany());
        user.setIndustry(request.getIndustry());
        user.setPosition(request.getPosition());
        
        // 密码加密
        String salt = UUID.randomUUID().toString().substring(0, 16);
        user.setSalt(salt);
        user.setPassword(passwordEncoder.encode(request.getPassword() + salt));
        
        // 设置默认值
        user.setStatus(1); // 启用状态
        user.setVipLevel(0);
        user.setExperienceYears(0);
        user.setVerificationStatus(0);
        user.setEmailVerified(0);
        user.setPhoneVerified(0);
        user.setLoginCount(0);
        user.setDeleted(0);
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        userDao.insert(user);
        
        log.info("用户注册成功，用户ID: {}, 用户名: {}", user.getId(), user.getUsername());
        return user;
    }

    @Override
    public String login(UserLoginRequest request) {
        // 根据用户名或邮箱查找用户
        User user = getUserByUsername(request.getUsername());
        if (user == null) {
            user = getUserByEmail(request.getUsername());
        }
        
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        if (user.getStatus() == 0) {
            throw new RuntimeException("用户已被禁用");
        }
        
        // 验证密码
        if (!passwordEncoder.matches(request.getPassword() + user.getSalt(), user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        // 生成JWT Token
        String token = jwtUtil.generateToken(user.getId().toString());
        
        log.info("用户登录成功，用户ID: {}, 用户名: {}", user.getId(), user.getUsername());
        return token;
    }

    @Override
    public User getUserByUsername(String username) {
        return userDao.selectByUsername(username);
    }

    @Override
    public User getUserById(Long id) {
        return userDao.selectById(id);
    }

    @Override
    public User getUserByEmail(String email) {
        return userDao.selectByEmail(email);
    }

    @Override
    public User updateUser(Long userId, UserUpdateRequest request) {
        User user = getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查邮箱是否已被其他用户使用
        if (request.getEmail() != null && !request.getEmail().equals(user.getEmail())) {
            if (existsByEmail(request.getEmail())) {
                throw new RuntimeException("邮箱已被其他用户使用");
            }
        }
        
        // 检查手机号是否已被其他用户使用
        if (request.getPhone() != null && !request.getPhone().equals(user.getPhone())) {
            if (existsByPhone(request.getPhone())) {
                throw new RuntimeException("手机号已被其他用户使用");
            }
        }
        
        // 更新用户信息
        if (request.getName() != null) user.setName(request.getName());
        if (request.getNickname() != null) user.setNickname(request.getNickname());
        if (request.getEmail() != null) user.setEmail(request.getEmail());
        if (request.getPhone() != null) user.setPhone(request.getPhone());
        if (request.getCompany() != null) user.setCompany(request.getCompany());
        if (request.getIndustry() != null) user.setIndustry(request.getIndustry());
        if (request.getPosition() != null) user.setPosition(request.getPosition());
        if (request.getLocation() != null) user.setLocation(request.getLocation());
        if (request.getWebsite() != null) user.setWebsite(request.getWebsite());
        if (request.getBio() != null) user.setBio(request.getBio());
        if (request.getExperienceYears() != null) user.setExperienceYears(request.getExperienceYears());
        
        // 处理兴趣和技能标签
        try {
            if (request.getInterests() != null) {
                user.setInterests(objectMapper.writeValueAsString(request.getInterests()));
            }
            if (request.getSkills() != null) {
                user.setSkills(objectMapper.writeValueAsString(request.getSkills()));
            }
        } catch (Exception e) {
            log.error("序列化标签数据失败", e);
        }
        
        user.setUpdatedAt(LocalDateTime.now());
        userDao.updateById(user);
        
        log.info("用户信息更新成功，用户ID: {}", userId);
        return user;
    }

    @Override
    public User updateUserAvatar(Long userId, String avatarUrl) {
        User user = getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setAvatar(avatarUrl);
        user.setUpdatedAt(LocalDateTime.now());
        userDao.updateById(user);
        
        log.info("用户头像更新成功，用户ID: {}", userId);
        return user;
    }

    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        User user = getUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证原密码
        if (!passwordEncoder.matches(oldPassword + user.getSalt(), user.getPassword())) {
            return false;
        }
        
        // 更新密码
        String newSalt = UUID.randomUUID().toString().substring(0, 16);
        user.setSalt(newSalt);
        user.setPassword(passwordEncoder.encode(newPassword + newSalt));
        user.setUpdatedAt(LocalDateTime.now());
        userDao.updateById(user);
        
        log.info("用户密码修改成功，用户ID: {}", userId);
        return true;
    }

    @Override
    public boolean resetPassword(String email) {
        User user = getUserByEmail(email);
        if (user == null) {
            return false;
        }
        
        // 生成临时密码
        String tempPassword = UUID.randomUUID().toString().substring(0, 8);
        String newSalt = UUID.randomUUID().toString().substring(0, 16);
        user.setSalt(newSalt);
        user.setPassword(passwordEncoder.encode(tempPassword + newSalt));
        user.setUpdatedAt(LocalDateTime.now());
        userDao.updateById(user);
        
        // TODO: 发送邮件通知用户新密码
        log.info("用户密码重置成功，用户ID: {}, 临时密码: {}", user.getId(), tempPassword);
        return true;
    }

    @Override
    public boolean verifyEmail(Long userId, String code) {
        // TODO: 实现邮箱验证逻辑
        User user = getUserById(userId);
        if (user != null) {
            user.setEmailVerified(1);
            user.setUpdatedAt(LocalDateTime.now());
            userDao.updateById(user);
            return true;
        }
        return false;
    }

    @Override
    public boolean verifyPhone(Long userId, String code) {
        // TODO: 实现手机验证逻辑
        User user = getUserById(userId);
        if (user != null) {
            user.setPhoneVerified(1);
            user.setUpdatedAt(LocalDateTime.now());
            userDao.updateById(user);
            return true;
        }
        return false;
    }

    @Override
    public boolean updateLoginInfo(Long userId, String loginIp) {
        User user = getUserById(userId);
        if (user != null) {
            user.setLastLoginTime(LocalDateTime.now());
            user.setLastLoginIp(loginIp);
            user.setLoginCount(user.getLoginCount() + 1);
            user.setUpdatedAt(LocalDateTime.now());
            userDao.updateById(user);
            return true;
        }
        return false;
    }

    @Override
    public List<User> getUserList(int page, int size, String keyword, String industry, String location) {
        // 计算正确的偏移量（页码从1开始，偏移量从0开始）
        int offset = (page - 1) * size;
        return userDao.selectUserList(offset, size, keyword, industry, location);
    }

    @Override
    public long getUserCount() {
        return userDao.selectCount(null);
    }

    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        User user = getUserById(userId);
        if (user != null) {
            user.setStatus(status);
            user.setUpdatedAt(LocalDateTime.now());
            userDao.updateById(user);
            return true;
        }
        return false;
    }

    @Override
    public boolean verifyUser(Long userId) {
        User user = getUserById(userId);
        if (user != null) {
            user.setVerificationStatus(1);
            user.setUpdatedAt(LocalDateTime.now());
            userDao.updateById(user);
            return true;
        }
        return false;
    }

    @Override
    public boolean existsByUsername(String username) {
        return userDao.selectByUsername(username) != null;
    }

    @Override
    public boolean existsByEmail(String email) {
        return userDao.selectByEmail(email) != null;
    }

    @Override
    public boolean existsByPhone(String phone) {
        return userDao.selectByPhone(phone) != null;
    }

    @Override
    public boolean followUser(Long followerId, Long followedId) {
        // 检查是否已关注
        if (isFollowing(followerId, followedId)) {
            return false;
        }
        
        UserFollow follow = new UserFollow();
        follow.setFollowerId(followerId);
        follow.setFollowedId(followedId);
        follow.setCreatedAt(LocalDateTime.now());
        
        userFollowDao.insert(follow);
        log.info("用户关注成功，关注者ID: {}, 被关注者ID: {}", followerId, followedId);
        return true;
    }

    @Override
    public boolean unfollowUser(Long followerId, Long followedId) {
        return userFollowDao.deleteByFollowerAndFollowed(followerId, followedId) > 0;
    }

    @Override
    public List<User> getFollowingList(Long userId, int page, int size) {
        int offset = (page - 1) * size;
        return userFollowDao.selectFollowingList(userId, offset, size);
    }

    @Override
    public List<User> getFollowersList(Long userId, int page, int size) {
        int offset = (page - 1) * size;
        return userFollowDao.selectFollowersList(userId, offset, size);
    }

    @Override
    public boolean isFollowing(Long followerId, Long followedId) {
        return userFollowDao.selectByFollowerAndFollowed(followerId, followedId) != null;
    }

    @Override
    public User createUser(User user) {
        // 检查用户名是否已存在
        if (existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (user.getEmail() != null && !user.getEmail().isEmpty() && existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 检查手机号是否已存在
        if (user.getPhone() != null && !user.getPhone().isEmpty() && existsByPhone(user.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 密码加密
        if (user.getPassword() != null && !user.getPassword().isEmpty()) {
            String salt = UUID.randomUUID().toString().substring(0, 16);
            user.setSalt(salt);
            user.setPassword(passwordEncoder.encode(user.getPassword() + salt));
        }
        
        // 设置默认值
        if (user.getStatus() == null) {
            user.setStatus(1); // 启用状态
        }
        if (user.getVipLevel() == null) {
            user.setVipLevel(0);
        }
        if (user.getExperienceYears() == null) {
            user.setExperienceYears(0);
        }
        if (user.getVerificationStatus() == null) {
            user.setVerificationStatus(0);
        }
        if (user.getEmailVerified() == null) {
            user.setEmailVerified(0);
        }
        if (user.getPhoneVerified() == null) {
            user.setPhoneVerified(0);
        }
        if (user.getLoginCount() == null) {
            user.setLoginCount(0);
        }
        if (user.getDeleted() == null) {
            user.setDeleted(0);
        }
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        userDao.insert(user);
        
        log.info("管理员创建用户成功，用户ID: {}, 用户名: {}", user.getId(), user.getUsername());
        return user;
    }

    @Override
    public User updateUser(User user) {
        if (user == null || user.getId() == null) {
            throw new RuntimeException("用户信息不能为空");
        }

        // 检查用户是否存在
        User existingUser = getUserById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 如果要更新用户名，检查是否与其他用户冲突
        if (user.getUsername() != null && !user.getUsername().equals(existingUser.getUsername())) {
            if (existsByUsername(user.getUsername())) {
                throw new RuntimeException("用户名已存在");
            }
        }

        // 如果要更新邮箱，检查是否与其他用户冲突
        if (user.getEmail() != null && !user.getEmail().equals(existingUser.getEmail())) {
            if (existsByEmail(user.getEmail())) {
                throw new RuntimeException("邮箱已存在");
            }
        }

        // 如果要更新手机号，检查是否与其他用户冲突
        if (user.getPhone() != null && !user.getPhone().equals(existingUser.getPhone())) {
            if (existsByPhone(user.getPhone())) {
                throw new RuntimeException("手机号已存在");
            }
        }

        // 保留某些不应被更新的字段
        user.setPassword(existingUser.getPassword());
        user.setSalt(existingUser.getSalt());
        user.setCreatedAt(existingUser.getCreatedAt());
        user.setUpdatedAt(LocalDateTime.now());

        userDao.updateById(user);
        
        log.info("管理员更新用户成功，用户ID: {}, 用户名: {}", user.getId(), user.getUsername());
        return user;
    }

    @Override
    public List<User> getAllUsers() {
        return userDao.selectList(null);
    }

    @Override
    public boolean deleteUser(Long id) {
        if (id == null) {
            return false;
        }
        int result = userDao.deleteById(id);
        if (result > 0) {
            log.info("用户删除成功，用户ID: {}", id);
            return true;
        }
        return false;
    }

    @Override
    public boolean batchUpdateStatus(List<Long> ids, Integer status) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        int updated = 0;
        for (Long id : ids) {
            User user = getUserById(id);
            if (user != null) {
                user.setStatus(status);
                user.setUpdatedAt(LocalDateTime.now());
                userDao.updateById(user);
                updated++;
            }
        }
        log.info("批量更新用户状态成功，更新数量: {}", updated);
        return updated > 0;
    }

    @Override
    public boolean resetPassword(Long id, String newPassword) {
        User user = getUserById(id);
        if (user != null) {
            String hashedPassword = passwordEncoder.encode(newPassword);
            user.setPassword(hashedPassword);
            user.setUpdatedAt(LocalDateTime.now());
            userDao.updateById(user);
            log.info("重置用户密码成功，用户ID: {}", id);
            return true;
        }
        return false;
    }

    @Override
    public List<User> getRecentUsers(Integer limit) {
        return userDao.selectRecentUsers(limit != null ? limit : 10);
    }

    @Override
    public List<User> searchUsers(String keyword, Integer page, Integer size) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return new ArrayList<>();
        }
        int offset = ((page != null ? page : 1) - 1) * (size != null ? size : 20);
        return userDao.searchUsers(keyword.trim(), offset, size != null ? size : 20);
    }

    @Override
    public Object getUserStats() {
        long totalUsers = getUserCount();
        long activeUsers = getActiveUserCount();
        long todayRegistrations = getTodayRegistrationCount();
        long todayLogins = getTodayLoginCount();

        Map<String, Object> stats = new HashMap<>();
        stats.put("total", totalUsers);
        stats.put("active", activeUsers);
        stats.put("todayRegistrations", todayRegistrations);
        stats.put("todayLogins", todayLogins);
        stats.put("verifiedUsers", userDao.countByVerificationStatus(1));
        stats.put("unverifiedUsers", userDao.countByVerificationStatus(0));
        return stats;
    }

    @Override
    public String exportUsers(String format) {
        // TODO: 实现用户数据导出功能
        log.info("导出用户数据，格式: {}", format);
        return "exports/users_" + System.currentTimeMillis() + "." + format.toLowerCase();
    }

    @Override
    public long getActiveUserCount() {
        return userDao.countByStatus(1);
    }

    @Override
    public long getTodayRegistrationCount() {
        return userDao.countTodayRegistrations();
    }

    @Override
    public long getTodayLoginCount() {
        return userDao.countTodayLogins();
    }
}